package com.svse.annotation;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.svse.util.IPUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * @author LiYuhang
 * @version 0.1
 * @application
 * @Copyright 上海危网信息科技有限公司版权所有
 * @company wwsoft
 * @Date 2019/11/21 15:02
 */
@Aspect
@Component
@Slf4j
public class SubmitLockAspect {
    @Resource
    private RedisTemplate stringRedisTemplate;

    @Pointcut("@within(com.svse.annotation.SubmitLock) || @annotation(com.svse.annotation.SubmitLock)")
    @Order(1)
    public void submitLock(){}

    @Around("submitLock()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            StringBuffer reqUrl = request.getRequestURL();
            String ip = IPUtils.getIpAddr(request);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(ip).append("|").append(reqUrl).append(Arrays.toString(point.getArgs()));
            //判断是否有值
            if (!stringRedisTemplate.hasKey(stringBuffer.toString())) {
                Object o = point.proceed();
                //redis存数据并 设置1分钟失效
                stringRedisTemplate.opsForValue().set(stringBuffer.toString(), "true", 60, TimeUnit.SECONDS);
                return o;
            } else {
                log.info("请勿重复提交数据");
                return "{\"code\":\"403\",\"message\":\"请勿重复提交！\"}";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("验证重复提交时出现异常！{}",e);
            return "{\"code\":\"500\",\"message\":\"验证重复提交时出现未知异常！\"}";
        }
    }
}
